﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using TTEngine.Graphics;
using TTEngine.TTMath;
using Silk.NET.OpenGLES;
using TTEngine.Resource;


namespace TTEngine.Graphics
{
    public class FontAscII12 : ResourceObj, IFont
    {
        public int FontSize => 12;

        Dictionary<char, ImageData> mapImage = new Dictionary<char, ImageData>();




        Dictionary<char, fAABB> mapUV = new Dictionary<char, fAABB>();
        public Texture2D texFont
        {
            get;
            private set;
        }
        public ImageData GetCharImage(char c)
        {
            return mapImage[c];
        }
        public bool TryGetUV(char c, out fAABB aabb)
        {
            return mapUV.TryGetValue(c, out aabb);
        }

        Dictionary<char, PackedFontCharInfo> mapChar = new Dictionary<char, PackedFontCharInfo>();

        public FontAscII12(ResourcePackage package, byte[] data, PackedTextureGroup group)
            : base(package)
        {
            int size = 12;
            //byte[] data = System.IO.File.ReadAllBytes(filename);

            byte halfsize = (byte)(size / 2);

            int bytewidth = halfsize / 8;
            if (halfsize % 8 > 0)
                bytewidth++;



            int datablocksize = size * bytewidth;

            for (var i = 32; i < 127; i++)//ascii key range
            {
                var cdata = new byte[size * halfsize];

                char c = (char)i;
                //TileInfo charinfo;
                int pixeloffsetX = int.MaxValue;
                int pixeloffsetY = int.MaxValue;
                //charinfo.pixeloffsetX = int.MaxValue;
                //charinfo.pixeloffsetY = int.MaxValue;
                int pixeloffsetXMax = int.MinValue;
                int pixeloffsetYMax = int.MinValue;

                bool empty = true;
                for (var y = 0; y < size; y++)
                {
                    var bit = data[(i - 32) * datablocksize + y];
                    if (bit == 0) continue;
                    for (var x = 0; x < 6; x++)
                    {
                        if (x >= halfsize) continue;
                        var mask = 1 << (7 - x);

                        if ((bit & mask) > 0)
                        {
                            cdata[y * halfsize + x] = 255;

                            if (pixeloffsetX > x)
                                pixeloffsetX = x;

                            if (pixeloffsetY > y)
                                pixeloffsetY = y;

                            if (pixeloffsetXMax < x) pixeloffsetXMax = x;
                            if (pixeloffsetYMax < y) pixeloffsetYMax = y;
                            empty = false;

                        }
                    }
                }
                if (empty)
                {
                    //空的还管他个屁
                    continue;
                }
                else
                {
                    int pixelSizeX = pixeloffsetXMax + 1 - pixeloffsetX;
                    int pixelSizeY = pixeloffsetYMax + 1 - pixeloffsetY;

                    var imgdata = new ImageData(halfsize, (uint)size, ImageFormat.Gray);
                    imgdata.SetData(cdata);
                    mapImage[(char)i] = imgdata;

                    //var s = texture.UpdateSprite_Cut(c.ToString(), halfsize, size, cdata, (byte)pixeloffsetX, (byte)pixeloffsetY, pixelSizeX, pixelSizeY);
                }

                //bool b = texture.GetFreeTile(out charinfo.tileX, out charinfo.tileY);
                //if (!b) throw new Exception("TiledTexture is Full");
                //texture.UploadTile(charinfo.tileX, charinfo.tileY, cdata);
                //font.charTable[c.ToString()] = charinfo;

            }

            this.PackGroup = group;
            InitTex();


        }
        protected override void OnDestory()
        {
            texFont?.TryDecRefAndDestory();
            texFont = null;
        }
        void InitTex()
        {

            var imgdata = new ImageData(128, 128, ImageFormat.Gray);

            int x = 0;
            int y = 0;
            foreach (var c in mapImage)
            {
                c.Value.CopyTo(imgdata, x, y);
                mapUV[c.Key] = new fAABB(x / 128.0f, y / 128.0f,
                    (x + 6) / 128.0f, (y + 12) / 128.0f);

                x += 6;
                if (x + 6 > 128)
                {
                    x = 0;
                    y += 12;
                }
            }
            unsafe
            {

                fixed (byte* dataptr = imgdata.GetData())
                {
                    texFont = new Texture2D(this.Package, 128, 128, TextureType.R_U8, dataptr);
                }
            

            }
            foreach (var c in mapImage)
            {
                var cinfo = new PackedFontCharInfo();
                cinfo.fontadv = 6;
                var data = new SpriteData(6, 12, ImageFormat.Gray, 0, 0);
                data.SetData(c.Value.GetData());
                cinfo.elem = PackGroup.AddSpriteInfo(data, SpriteEffect.GrayAsAlpha, Border.Zero);
                mapChar[c.Key] = cinfo;
            }
            PackGroup.ApplyTextureData();
        }

        public bool EnsureTextPacked(string text) => false;

        public void ApplyPackedTextureData()
        {

        }

        public bool TryGetCharInfo(int c, out PackedFontCharInfo value)
        {
            return mapChar.TryGetValue((char)c, out value);
        }

        public PackedTextureGroup PackGroup
        {
            get;
            private set;
        }
    }
}
